package com.lagou.binding;

import com.lagou.pojo.Configuration;
import com.lagou.sqlSession.SqlSession;

import java.util.HashMap;
import java.util.Map;

/**
 * Mapper 注册表
 */
public class MapperRegistry {

    private final Configuration config;
    /**
     * Mapper:MapperProxyFactory 的映射
     */
    private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

    public MapperRegistry(Configuration config) {
        this.config = config;
    }

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        // 获得 MapperProxyFactory 对象
        final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
        // 不存在，则抛出 BindingException 异常
        if (mapperProxyFactory == null) {
            throw new RuntimeException("Type " + type + " is not known to the MapperRegistry.");
        }
        /// 通过动态代理工厂生成实例。
        try {
            return mapperProxyFactory.newInstance(sqlSession);
        } catch (Exception e) {
            throw new RuntimeException("Error getting mapper instance. Cause: " + e, e);
        }
    }

    public <T> void addMapper(Class<T> type) {
        // 判断，必须是接口。
        if (type.isInterface()) {
            // 添加到 knownMappers 中
            knownMappers.put(type, new MapperProxyFactory<>(type));
        }
    }

}